package com.gitee.wsl.data.store.db


import androidx.room.ColumnInfo
import androidx.room.Database
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import androidx.room.RoomDatabase
import androidx.room.RoomDatabaseConstructor
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import com.gitee.wsl.ext.db.DB
import com.gitee.wsl.ext.db.LocalDateTimeConverter
import com.gitee.wsl.data.store.db.Constants.COL_ID
import com.gitee.wsl.data.store.db.Constants.COL_KEY
import com.gitee.wsl.data.store.db.Constants.COOl_VALUE
import com.gitee.wsl.data.store.db.Constants.kvStoreTableName
import com.gitee.wsl.ext.db.roomDatabaseBuilder
import com.gitee.wsl.io.cache.db.DB_Cache_NAME
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO


@Entity(tableName = kvStoreTableName,
    indices = [Index(value = [COL_KEY], unique = true)])
data class KVStore(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = COL_ID) var id: Long = 0,
    @ColumnInfo(name = COL_KEY) var key:String,
    @ColumnInfo(name = COOl_VALUE) var value:String
    )


@Database(
    exportSchema = true,
    entities = [KVStore::class],
    version = 1)
@TypeConverters(LocalDateTimeConverter::class)
abstract class KVStoreDatabase : RoomDatabase() ,DB{
    abstract fun kvStoreDao(): KVStoreDao

    override fun clearAllTables() {
        //super.clearAllTables()
    }

    /* companion object {
        // For Singleton instantiation
        @Volatile
        private var instance: KVStoreDatabase? = null

        *//**
         * Use this in tests only
         *//*
        internal fun setInstance(db: KVStoreDatabase) {
            instance = db
        }

        fun getInstance(context: Context): KVStoreDatabase {
            return instance
                ?: synchronized(this) {
                    instance
                        ?: buildDatabase(context).also { instance = it }
                }
        }

        private fun buildDatabase(context: Context): KVStoreDatabase {
            val dbBuilder = Room.databaseBuilder(context, KVStoreDatabase::class.java, kvStoreDatabaseName)

            dbBuilder.setQueryCallback(queryCallback = object:QueryCallback{
                override fun onQuery(sqlQuery: String, bindArgs: List<Any?>) {
                    println("SQL Query: $sqlQuery SQL Args: $bindArgs")
                }
            }*//*{sqlQuery, bindArgs ->
                println("SQL Query: $sqlQuery SQL Args: $bindArgs")
            }*//*, Executors.newSingleThreadExecutor())


            return dbBuilder.build()
        }

        fun init(context: Application){
            getInstance(context)
        }
    }*/
    companion object
}

// The Room compiler generates the `actual` implementations.
//@Suppress("NO_ACTUAL_FOR_EXPECT")
//expect object KVStoreDatabaseConstructor : RoomDatabaseConstructor<KVStoreDatabase> {
//    override fun initialize(): KVStoreDatabase
//}

fun KVStoreDatabase.Companion.create(name: String = DB_Cache_NAME, isMultiInstance: Boolean = false) = getKVStoreDatabase(roomDatabaseBuilder(name,  isMultiInstance))


const val DB_KVStore_NAME = "KVStore"

val MIGRATIONS = arrayOf<Migration>()

fun getKVStoreDatabase(builder: RoomDatabase.Builder<KVStoreDatabase>): KVStoreDatabase = builder
    .addMigrations(*MIGRATIONS)
    .fallbackToDestructiveMigrationOnDowngrade(true)
    .setDriver(BundledSQLiteDriver())
    .setQueryCoroutineContext(Dispatchers.IO)
    .build()